package leetcode.top100;



/**
 * 输入: "   -42"
 * 输出: -42
 * 解释: 第一个非空白字符为 '-', 它是一个负号。
 *      我们尽可能将负号与后面所有连续出现的数字组合起来，最后得到 -42
 * <p>
 * 输入: "4193 with words"
 * 输出: 4193
 * 解释: 转换截止于数字 '3' ，因为它的下一个字符不为数字。
 * <p>
 * 输入: "words and 987"
 * 输出: 0
 * 解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
 * 因此无法执行有效的转换。
 * <p>
 * 输入: "-91283472332"
 * 输出: -2147483648
 * 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。
 *      因此返回 INT_MIN (−231)
 *
 *@date 2019/11/15 0015 下午 12:03
 */
public class Code08_IntegerParseInt {


    /**
     * 通过测试
     */
    public static int myAtoi(String str) {
        if (str == null || str.length() == 0) {
            return 0;
        }
        int len = str.length();
        int index = 0;
        int negative = 1;
        int res = 0;
        //1. 去除前导空格,注意只有前导空格情况"   "
        while (index < len && str.charAt(index) == ' ' ){
            index++;
        }
        // 只有前导空格
        if(index == len){
            return 0;
        }
        //2考虑 + -
        if (str.charAt(index) < '0' || str.charAt(index) > '9') {
             if(str.charAt(index) != '-' && str.charAt(index) != '+'){
                return res;
            }
            if (str.charAt(index) == '-') {
                negative = -1;
            }
            // if only + or -
            if (index == len - 1) {
                return res;
            }
            index++;
        }
        //3 其他位。注意判断是越界
        while (index < len) {
            //3.1如果后面是非法数字，直接返回当前结果
            if (!digital(str, index)) {
                return res;
            }
            //3.2题目要求如果越界则输入上下界
            if (isBound(res, str.charAt(index))) {
                return negative == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
            }
            res = res * 10 + negative * (str.charAt(index) - '0');
            index++;
        }
        return res;
    }

    private static boolean isBound(int res, char ch) {
        int upBound = Integer.MAX_VALUE % 10;
        int lowBound = Integer.MIN_VALUE % 10;
        if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && ch - '0'> upBound)) {
            return true;
        }
        if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && ch - '0'> Math.abs(lowBound))) {
            return true;
        }
        return false;
    }

    private static boolean digital(String str, int index) {
        return str.charAt(index) >= '0' && str.charAt(index) <= '9';
    }

    public static void main(String[] args) {
//        System.out.println(myAtoi("-42"));
        System.out.println(myAtoi("-91283472332"));
//        System.out.println(myAtoi("+2147483647"));
//        System.out.println(Integer.MAX_VALUE);
    }
}
